﻿using LibNiconico.NiconicoApi.Internal.Http;
using LibNiconico.NiconicoApi.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace LibNiconico.NiconicoApi.Internal
{
    /// <summary>
    /// ニコニコ情報取得APIベースクラス
    /// </summary>
    internal  class NiconicoInfoGetApiImpl:IDisposable
        
    {


        /// <summary>
        /// 対象URL
        /// </summary>
        //protected abstract Uri TargetBaseUrl { get; }
        private INiconicoHttpClient api;

        internal Uri TargetUrl { get; private set; }

        

        internal void AddHeader(string name, string value)
        {
            api.AddHeader(name, value);
        }


        internal void SetCookies(CookieCollection cookies)
        {
            this.api.SetCookies(TargetUrl, cookies);
        }

        /// <summary>
        /// 指定した名前のクッキーを取得
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        protected Cookie GetCookie(string name)
        {
            var cookies = api.CookieContainer;
            if (cookies != null && cookies.Count > 1)
            {
                return cookies.GetCookies(TargetUrl)[name];
            }

            return null;
        }
        internal CookieContainer GetCookie()
        {
            return this.api.CookieContainer;
        }

        internal NiconicoInfoGetApiImpl(Uri url, INiconicoHttpClient api)
        {
            TargetUrl = url;
            this.api = api;
        }






        internal async Task<NiconicoHttpResponse<string>> GetStringAsync(NicoUrlAble urlAble)
        {
            return await api.GetStringAsync(CreateFrom(urlAble)).ConfigureAwait(false);
        }

        internal async Task<NiconicoHttpResponse<Stream>> GetStreamAsync(NicoUrlAble urlAble)
        {
            return await api.GetStreamAsync(CreateFrom(urlAble)).ConfigureAwait(false);
        }

        internal async Task<NiconicoHttpResponse<string>> PostStringAsync(NicoPostAble postAble)
        {
            return await api.PostStringAsync(CreateFrom(postAble), postAble).ConfigureAwait(false);
        }

        internal async Task<NiconicoHttpResponse<Stream>> PostStreamAsyunc(NicoPostAble postAble)
        {
            return await api.PostStreamAsync(CreateFrom(postAble), postAble).ConfigureAwait(false);
        }

        internal async Task<NiconicoHttpResponse<CookieContainer>> GetCookieAsync(NicoUrlAble urlAble)
        {
            return await api.GetCookieAsync(CreateFrom(urlAble)).ConfigureAwait(false);
        }

        internal async Task PostTaskAsync(NicoPostAble postAble)
        {
            await api.PostAsync(CreateFrom(postAble), postAble).ConfigureAwait(false);
        }

        internal async Task<NiconicoHttpResponse<CookieContainer>> PostCookieAsync(NicoPostAble postAble)
        {
            return await api.PostCookieAsync(CreateFrom(postAble), postAble).ConfigureAwait(false);
        }


        private Uri CreateFrom(NicoUrlAble urlAble)
        {
            UriBuilder builder = new UriBuilder(TargetUrl.Scheme, TargetUrl.Host, TargetUrl.Port);
            string path = urlAble.AsPath();
            string extraValue = urlAble.AsQuery();

            if(path != "")builder.Path = urlAble.AsPath();
         
            
            if(extraValue != "")builder.Query = urlAble.AsQuery();



            return builder.Uri;
        }

        /// <summary>
        /// このオブジェクトに割り当てられているリソースを解放
        /// </summary>
        public void Dispose()
        {
            this.api.Dispose();
        }
    }
}
